package online.inote.common.base;

import java.io.Serializable;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import com.alibaba.fastjson.JSON;

import online.inote.common.exception.BusException;

/**
 * <p>
 * Desc: 
 * </p>
 *
 * @author XQF SUI
 * @created 2018年8月20日 上午10:44:20
 * @version 1.0
 */
public class ESService<T extends IdEntity, ID extends Serializable> extends BaseService<T> {
	@Autowired
	protected ElasticsearchRepository<T, ID> repository;
	@Autowired
	protected ElasticsearchTemplate elasticTemplate;

	public boolean createIndex() {
		logger.info("创建ES索引, CLASS:[ {} ]", CLASS);
		
		if (isExistsIndex()) {
			logger.info("ES索引已存在, CLASS:[ {} ]", CLASS);
			throw new BusException("索引已存在");
		}
		
		boolean createIndex = elasticTemplate.createIndex(CLASS);
		
		if (createIndex) {
			logger.info("ES索引创建成功, CLASS:[ {} ]", CLASS);
		} else {
			logger.info("ES索引创建失败, CLASS:[ {} ]", CLASS);
		}
		
		return createIndex;
	}
	
	public boolean deleteIndex() {
		logger.info("删除ES索引, CLASS:[ {} ]", CLASS);
		
		if (!isExistsIndex()) {
			logger.info("ES索引不存在, CLASS:[ {} ]", CLASS);
		}
		
		return elasticTemplate.deleteIndex(CLASS);
	}
	
	public boolean isExistsIndex() {
		logger.info("查询ES索引是否存在, CLASS:[ {} ]", CLASS);
		boolean isExists = elasticTemplate.indexExists(CLASS);
		logger.info(isExists ? "ES索引已存在, CLASS:[ {} ]" : "ES索引不存在, CLASS:[ {} ]", CLASS);
		
		return isExists;
	}
	
	public boolean putMapping() {
		logger.info("putMapping, CLASS:[ {} ]", CLASS);
		return elasticTemplate.putMapping(CLASS);
	}
	
	public Map<?, ?> getMapping() {
		logger.info("getMapping, CLASS:[ {} ]", CLASS);
		Map<?, ?> mapping = elasticTemplate.getMapping(CLASS);
		logger.info("Mapping info:[ {} ], CLASS:[ {} ]", JSON.toJSONString(mapping), CLASS);
		
		return mapping;
	}
	
	public Page<T> selectESPage(Page<T> page, Criteria criteria, Sort sort) {
		Pageable pageable = PageRequest.of(page.getESPage(), page.getRows(), sort);
		CriteriaQuery criteriaQuery = new CriteriaQuery(criteria, pageable);
		org.springframework.data.domain.Page<T> esPage = elasticTemplate.queryForPage(criteriaQuery, CLASS);
		
		page.setDataList(esPage.getContent());
		page.setRecords(esPage.getTotalElements());
		
		return page;
	}
}
